<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">
            
            /*
             * 作用域
             *     - 作用域指一个变量的作用的范围

             *     - 在JS中一共有两种作用域：
             *         1.全局作用域
             *             - 直接编写在script标签中的JS代码，都在全局作用域
             *             - 全局作用域在页面打开时创建，在页面关闭时销毁
             *             - 在全局作用域中有一个全局对象window，
             *                 它代表的是一个浏览器的窗口，它由浏览器创建我们可以直接使用
             *             - 在全局作用域中：
             *                 创建的变量都会作为window对象的属性保存
             *                 创建的函数都会作为window对象的方法保存
			 *                 所谓的函数都是window对象的方法
             *             - 全局作用域中的变量都是全局变量，
             *                 在页面的任意的部分都可以访问全局变量
             * 
             *         2.函数作用域  
             *     
             *        - 调用函数时创建函数作用域，函数执行完毕以后，函数作用域销毁
             *     
             *        - 每调用一次函数就会创建一个新的函数作用域，他们之间是互相独立的

             *        - 定义形参就相当于在函数作用域中声明了变量

             *        - 在函数作用域中可以访问到全局作用域的变量
             *            在全局作用域中无法访问到函数作用域的变量
             *     
             *        - 当在函数作用域操作一个变量时，它会先在自身作用域中寻找，如果有就直接使用
             *            如果没有则向上一级作用域中寻找，直到找到全局作用域，
             *            如果全局作用域中依然没有找到，则会报错ReferenceError
             *     
             *        - 在函数中要访问全局变量可以使用window对象

                    两者之间的关系： 在函数中，不使用var声明的变量都会成为全局变量
             */
            
            //创建一个变量
            var a = 10;//全局变量10
            function fun(){
                var a = "我是fun函数中的变量a";
                var b = 20;
                console.log("a = "+a); //a = 我是fun函数中的变量a
                function fun2(){
                    console.log("a = "+a);//a = 我是fun函数中的变量a
                    //不加window就是就近原则，加就是全局的
                    a=11;
                    console.log("a = "+a);
                    console.log("a = "+window.a);//a = 10
                }
                fun2();
                 
            }
            fun();
            console.log("a = "+a);//a = 10
            //在全局作用域中无法访问到函数作用域的变量
            // console.log("b = "+b);//Uncaught ReferenceError: b is not defined
            //-------------------------------------------------------------------------------
			
			
			/*
             * 在函数作用域也有声明提前的特性，
             *     使用var关键字声明的变量，会在函数中所有的代码执行之前被声明
             *     函数声明也会在函数中所有的代码执行之前执行
             */
            
             var ss=90;
            function gg(){
                console.log("ss="+ss)  //ss=undefined 因为变量声明提前  所以不是没有变量
                var ss=88; 
               
            }
            gg();


            function fun3(){ 
                
                fun4();
                
                console.log(a);//undefined
                
                var a = 35;
                
                function fun4(){ 
                    alert("I'm fun4");
                }
                
            }
            
            fun3(); 
            
            
            //--------------------------------------------------------------------------------
            
            
            var c = 33;
            
            /*
             * 在函数中，不使用var声明的变量都会成为全局变量，但是不会变量提前
             */
            function fun5(){
                
                console.log("c = "+c);//c = 33
                c = 10;
                
                //d没有使用var关键字，则会设置为全局变量
                d = 100;
            }
            
            fun5();
            
            //在全局输出c
            console.log("d = "+d);//d = 100
            
            
            //--------------------------------------------------------------------------------
            
            
            var e = 23;
            
            /*
             * 定义形参就相当于在函数作用域中声明了变量
             */
            function fun6(e){
                console.log("e = "+e); //e = undefined，相当于在函数作用域里面声明了一个变量var e;
            }
            
            fun6();
            
        </script>
    </head>
    <body>
    </body>
</html>